import 'package:flutter/material.dart';
import 'package:hi_net/db/hi_cache.dart';
import 'package:hi_net/http/dio/login_dao.dart';
import 'package:hi_net/page/video_detail_page.dart';
import 'package:hi_net/model/video_model.dart';
import 'package:hi_net/page/home_page.dart';
import 'package:hi_net/page/login_page.dart';
import 'package:hi_net/page/main_page.dart';
import 'package:hi_net/page/register_page.dart';
import 'package:hi_net/util/color.dart';
import 'package:hi_net/util/toast.dart';

import 'navigator/hi_navigator.dart';

void main() {
  runApp(const HiApp());
}

class HiApp extends StatefulWidget {
  const HiApp({super.key});

  @override
  State<HiApp> createState() => _HiAppState();
}

class _HiAppState extends State<HiApp> {
  final _routeDelegate = HiRouteDelegate();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: HiCache.preInit(),
        builder: (context, snapshot) {
          // 定义route
          var widget = snapshot.connectionState == ConnectionState.done
              ? Router(routerDelegate: _routeDelegate)
              : const Scaffold(body: Center(child: CircularProgressIndicator()));
          return MaterialApp(home: widget, theme: ThemeData(primarySwatch: white));
        });
  }
}

class HiRouteDelegate extends RouterDelegate<HiRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<HiRoutePath> {
  //为Navigator设置一个key，必要的时候可以通过navigatorKey.currentState来获取到NavigatorState对象
  HiRouteDelegate() : navigatorKey = GlobalKey<NavigatorState>() {
    ///注册路由跳转监听，实现路由跳转逻辑
    HiNavigator.getInstance.registerRouteJump(RouteJumpListener(onJumpTo: (RouteStatus routeStatus, {Map? args}) {
      _routeStatus = routeStatus;
      if (routeStatus == RouteStatus.detail) {
        videoModel = args?['videoModel'];
      }
      notifyListeners();
    }));
  }

  RouteStatus _routeStatus = RouteStatus.main;
  List<MaterialPage> pages = [];
  VideoModel? videoModel;

  @override
  GlobalKey<NavigatorState> navigatorKey;

  @override
  Widget build(BuildContext context) {
    print("routerStatus $routerStatus");
    var index = getPageIndex(pages, routerStatus);
    List<MaterialPage> tempPages = pages;
    if (index != -1) {
      //要打开的页面在栈中已存在，则将该页面和它上面的所有页面进行出栈
      //tips 具体规则可以根据需要进行调整，这里要求栈中只允许有一个同样的页面的实例
      tempPages = tempPages.sublist(0, index);
    }

    var page;
    if (routerStatus == RouteStatus.main) {
      //跳转首页时将栈中其它页面进行出栈，因为首页不可回退
      pages.clear();
      page = pageWrap(const MainPage());
    } else if (routerStatus == RouteStatus.detail) {
      page = pageWrap(VideoDetailPage(videoModel!));
    } else if (routerStatus == RouteStatus.register) {
      page = pageWrap(const RegisterPage());
    } else if (routerStatus == RouteStatus.login) {
      page = pageWrap(const LoginPage());
    }
    //重新创建一个数组，否则pages因引用没有改变路由不会生效
    tempPages = [...tempPages, page];
    //通知路由发生变化
    HiNavigator.getInstance.notify(tempPages, pages);
    pages = tempPages;

    return WillPopScope(
        child: Navigator(
          key: navigatorKey,
          pages: pages,
          onPopPage: (route, result) {
            if (route.settings is MaterialPage) {
              //登录页未登录返回拦截
              if ((route.settings as MaterialPage).child is LoginPage) {
                if (!hasLogin) {
                  showWarnToast("请先登录");
                  return false;
                }
              }
            }

            //执行返回操作
            if (!route.didPop(result)) {
              return false;
            }
            var tempPages = [...pages];
            pages.removeLast();
            //通知路由发生变化
            HiNavigator.getInstance.notify(pages, tempPages);
            return true;
          },
        ),
        //fix Android物理返回键，无法返回上一页问题@https://github.com/flutter/flutter/issues/66349
        onWillPop: () async => !(await navigatorKey.currentState?.maybePop() ?? false));
  }

  /// 获取当前应该跳转到的页面的路由状态
  RouteStatus get routerStatus {
    // 拦截路由，未登录，跳转登录
    if (_routeStatus != RouteStatus.register && !hasLogin) {
      return _routeStatus = RouteStatus.login;
    }
    if (videoModel != null) {
      return _routeStatus = RouteStatus.detail;
    }
    return _routeStatus;
  }

  bool get hasLogin => LoginDao.getBoardingPass() != null;

  @override
  Future<void> setNewRoutePath(HiRoutePath configuration) async {}
}

///定义路由数据，path
class HiRoutePath {
  final String location;

  // 定义home构造方法
  HiRoutePath.home() : location = "/";

  HiRoutePath.detail() : location = "/detail";
}
